#include "ParserDone.h"

const string ParserDone::regexInstructionAndArguments = "\\s*([a-zA-Z]+)\\s*(.*)";

const string ParserDone::regexArgumentDoneTaskID = "\\s*([0-9]+)\\s*";
const string ParserDone::regexArgumentDoneSearchTerm = "\\s*(\\S.*?)\\s*";

const string ParserDone::regexInstructionDone = "(done)";

ParserDone::ParserDone(ParserBase* _nextParser) : ParserBase(_nextParser) {
}

bool ParserDone::tryParse(string userCommand, PARSED_COMMAND& parsedCommand){
	
	string instruction;
	string arguments;
	getInstructionAndArguments(userCommand, instruction, arguments);
	
	if (!checkInstruction(instruction)) {
		return false;
	}

	parseDone(parsedCommand, arguments);

	return true;
}

bool ParserDone::getInstructionAndArguments(const string& userCommand, 
										string& instruction, 
										string& arguments) {
	regex rgx(regexInstructionAndArguments);
	smatch matchResults;

	if (!regex_match(userCommand, matchResults, rgx)) {

		return false;
	}

	assert(matchResults.size () > ARGUMENTS_POS);
	instruction = matchResults[INSTRUCTION_POS];
	arguments = matchResults[ARGUMENTS_POS];


	return true;
}

bool ParserDone::checkInstruction(const string& instruction) {
	if (regex_match(instruction, regex(regexInstructionDone,
									   tr1::regex_constants::icase))) {
		return true;
	}

	return false;
}

void ParserDone::parseDone(PARSED_COMMAND& parsedCommand,
				  const string& arguments) {
	smatch matchResults;

	if (regex_match(arguments, matchResults, 
			regex(regexArgumentDoneTaskID))) {
		
		parsedCommand.commandType = DONE_TASKID;
		try {
			parsedCommand.doneTaskID = 
				getTaskIDFromArgument(matchResults[ARGUMENT_POS_DONE_TASKID]);
		}catch (range_error&) {
			parsedCommand.commandType = INVALID;
			parsedCommand.errorType = parsedCommand.ERROR_INVALID_TASK_INDEX;
	}
	}else if (regex_match(arguments, matchResults, 
		regex(regexArgumentDoneSearchTerm, tr1::regex_constants::icase))) {
		
		parsedCommand.commandType = DONE_SEARCHTERM;
		parsedCommand.doneSearchTerm = matchResults[ARGUMENT_POS_DONE_SEARCHTERM];
	}else {
		parsedCommand.commandType = INVALID;
		parsedCommand.errorType = parsedCommand.ERROR_FORMAT_DONE;
	}
}
